#ifndef EVENTLOOP_IOCHANNEL_H
#define EVENTLOOP_IOCHANNEL_H

#include "utility/Noncopyable.h"
#include "utility/chrono.h"
#include "utility/func.h"

#include <memory>

class Eventloop;
class IOchannelProxy;

/// @class owned by independent IO thread
/// @brief IO event handler
class IOchannel final {
public:
    IOchannel(Eventloop &loop, int fd, std::string name = {});
    ~IOchannel();

    Eventloop &eventloop() const;
    int fd() const { return _fd; }
    bool is_in_loop() const { return _inLoop; }
    const std::string &name() const { return _name; }

    void set_close_callback(const TrivialFunc &callback);
    void set_error_callback(const TrivialFunc &callback);
    void set_read_callback(const TimepointFunc &callback);
    void set_write_callback(const TrivialFunc &callback);

    void disable();
    void disable_reading();
    void disable_writing();
    void enable_reading();
    void enable_writing();
    bool is_idling() const;
    bool is_reading() const;
    bool is_writing() const;
    void remove();
    void tie(const std::shared_ptr<void> &obj);


private:
    NONCOPYABLE(IOchannel);

    void _update();

    const std::string _name;
    std::unique_ptr<IOchannelProxy> _proxy;
    const int _fd;
    bool _inLoop;
};


#endif